<?php


namespace app\common\business;

use app\common\lib\Snowflake;
use app\common\model\mysql\Order as OrderModel;
use app\common\model\mysql\OrderGoods as OrderGoodsModel;
use think\Exception;
use think\facade\Cache;

class Order extends BusBase
{
    public $model = NULL;
    public function __construct(){
        $this->model = new OrderModel();
    }

	/**
	 * 订单创建
	 * @param $data
	 * @return array|false|int
	 * @throws Exception
	 */
    public function save($data){
        // 雪花算法类库生成订单号
        $workId = rand(1,1023);
        $orderId = Snowflake::getInstance()->setWorkId($workId)->id();
        // 获取购物车列表数据 => redis
        $cartObj = new Cart();
        $result = $cartObj->lists($data['user_id'], $data['ids']);
        if(!$result){
            return false;
        }
        $price = array_sum(array_column($result, "total_price"));
        // order_goods表数据
        $newResult = array_map(function($v) use ($orderId){//闭包
            $v['sku_id'] = $v['id'];
            unset($v['id']);// order_goods表有自增id
			unset($v['total_price']);
            $v['order_id'] = $orderId;
            $v['create_time'] = date("Y-m-d H:i:s",$v['create_time']);
            return $v;
        }, $result); // $v是$result数组中的每一条数据
        // order表数据
        $orderData = [
            "user_id" => $data['user_id'],
            "order_id" => $orderId,
            "total_price" => $price,
            "address_id" => $data['address_id'],
        ];
        $this->model->startTrans();
        try {
            // 新增 order
            $id = $this->add($orderData);
            if(!$id){
                return 0;
            }
            // 新增 order_goods
			// dump($newResult);die;
            $orderGoodsResult = (new OrderGoodsModel())->saveAll($newResult);
            // goods_sku 更新
            $skuRes = (new GoodsSku())->updateStock($result);
            // goods 库存更新(延迟更新问题不大，因为是总库存，但是sku的库存必须要实时准确更新) 可以采用（Redis或者kafuka）消息队列异步处理
            // 删除购物车里面的商品
            $cartObj->deleteRedis($data['user_id'], $data['ids']);
            $this->model->commit();
            // 延迟队列不能影响正常的业务逻辑 放在事务提交之后
			// Redis的延迟队列(有序集合)：使用场景（无效订单处理  发货提醒  发邮件）
            // 生成订单时把当前订单ID 放入延迟队列中给个分数是当前时间＋订单失效时间，定期检测订单是否已经支付，（因为订单有效期是20分钟，超过这个时间还没有支付的）
            // 我们需要把这个订单取消，然后库存+操作
            try {
                // Redis 有序集合 zadd(key,score,member1)
                Cache::zAdd(config("redis.order_status_key"), time() + config("redis.order_expire"), $orderId);
            } catch (Exception $e){
                // 记录日志，添加监控，异步根据监控内容处理
            }
            return ["id" => $orderId];
        } catch (Exception $e){
            $this->model->rollback();
            return false;
        }
    }

	/**
	 * 订单详情
	 * @param $data
	 * @return array|array[]|\array[][]|mixed
	 */
    public function detail($data){
        // user_id 订单ID组合查询
        $condition = [
            "user_id" => $data["user_id"],
            "order_id" => $data["order_id"],
        ];
        try {
            $orders = $this->model->getByCondition($condition);
        } catch(Exception $e){
            $orders = [];
        }
        if(!$orders){
            return [];
        }
        $orders = $orders->toArray();
        $orders = !empty($orders) ? $orders[0] : [];
        if(empty($orders)){
            return [];
        }
        $orders['id'] = $orders['order_id'];
        $orders['consignee_info'] = "江西省 抚远市 东校区";
        // 根据order_id查询 order_goods表信息数据
        $orderGoods = (new OrderGoods())->getByOrderId($data['order_id']);
        $orders['malls'] = $orderGoods;
        return $orders;
    }

	/**
	 * worker消耗延迟队列中的数据
	 * @return bool
	 */
    public function checkOrderStatus(){
        $result = Cache::zRangeByScore("order_status", 0, time(), ['limit' => [0, 1]]);//order_status要配置在全局配置中才能用config()获取到 Redis配置也要配置在全局才可以使用 TP6 bug 获取1条来处理
        if(empty($result) || empty($result[0])){
            return false;
        }
        try {
            $delRedis = Cache::zRem("order_status", $result[0]);
        } catch (Exception $e){
            // 记录日志
            $delRedis = "";
        }
        if($delRedis){
			// 此处逻辑要放在事务中
            echo "订单id：{$result[0]}在规定时间内没有完成支付 我们判定为无效订单删除".PHP_EOL;
            // 第一步:根据订单ID 去数据库order表里面获取当前这条订单数据，看下当前状态是不是待支付:status = 1
            // 如果是那么我们需要把状态更新为 已取消 status = 7,否则不需要关心
            // 第二步：如果第一步status修改7之后，我们需要再查询order_goods表，拿到sku_id num 把sku表数据库存增加num
            // goods表总库存也需要修改
			// 不用把失效订单加回购物车
        } else {
            return false;
        }
        return true;
    }
}
